package jalus.service;

import jalus.dao.PostDAO;
import jalus.pojo.Post;
import jalus.utils.MyUtils;
import jalus.utils.PojoHandler;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheFactory;
import javax.cache.CacheManager;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

public class PostService {
	private static PostService instance  = new PostService();
	private PostDAO postDAO;
	private Cache cache;
	private PostService(){
		postDAO = new PostDAO();
		try {
			CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
			cache = cacheFactory.createCache(Collections.emptyMap());
		} catch (CacheException e) {
			cache = null;
		}
	}
	public static PostService getInstance(){
		return instance;
	}
	/**
	 * 获得所有文章
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<jalus.pojo.Post> getAllPostList(){
		String key = "getAllPost";
		if(!cache.containsKey(key)){
			cache.put(key, PojoHandler.copyMToPList(postDAO.getAllPost()));
		}
		return (List<jalus.pojo.Post>) cache.get(key);
	}
	
	
	/**
	 * 按照指定偏移和tag获得制定数目的post
	 * @param tag could be null
	 * @param offsetflag coule be null
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<jalus.pojo.Post> getPostListByOffsetAndTag(String tag, String offsetflag, int length){
		String key = "getPostByPage@" + tag + "_" + offsetflag + "_" + length;
		if(cache.containsKey(key)){
			return (List<jalus.pojo.Post>)cache.get(key);
		}
		
		long ms = NumberUtils.toLong(offsetflag);
		Date startDate;
		if(ms == 0){
			startDate = null;
		}else{
			startDate = new Date(ms);
		}
		List<jalus.pojo.Post> postList;
		if(StringUtils.isEmpty(tag)){
			postList = PojoHandler.copyMToPList(this.postDAO.getPostListByDate(startDate, length));
		}else{
			postList = PojoHandler.copyMToPList(this.postDAO.getPostListByTagAndDate(tag, startDate, length));
		}
		for(jalus.pojo.Post post : postList){
			post.setCommentCount(getCommentCountByPost(post.getId()));
		}
		cache.put(key, postList);
		return postList;
	}
	
	/**
	 * 获得一个月内的文章
	 * @param date
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<jalus.pojo.Post> getPostListByMonth(String archive){
		String key = "getPostListByMonth@" + archive;
		if(cache.containsKey(key)){
			return (List<Post>)cache.get(key);
		}
		
		Date date = MyUtils.parseDateCCT(archive, ArchiveService.dateFormat);
		Date beginDate = MyUtils.getMonthBeginDateCCT(date);
		Date endDate = MyUtils.getMonthEndDateCCT(date);
		List<jalus.pojo.Post> postList = PojoHandler.copyMToPList(
				this.postDAO.getPostListByDateRange(beginDate, endDate));
		for(jalus.pojo.Post post : postList){
			post.setCommentCount(getCommentCountByPost(post.getId()));
		}
		cache.put(key, postList);
		return postList;
	}
	
	
	
	/**
	 * 根据id获取Post
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public jalus.pojo.Post getPostById(Long id){
		String key = "getPostById@" + id;
		if(!cache.containsKey(key)){
			cache.put(key, PojoHandler.copyMToP(postDAO.getPostById(id)));
		}
		jalus.pojo.Post post = (jalus.pojo.Post)cache.get(key);
		post.setCommentCount(getCommentCountByPost(post.getId()));
		return post;
	}
	
	/**
	 * 根据传入的参数，更新Post
	 * @param post
	 */
	public void updatePost(jalus.model.Post post){
		jalus.model.Post oldPost = postDAO.getPostById(post.getId());
		post.setDate(oldPost.getDate());
		if(oldPost.isVisiable() && !post.isVisiable()){
			TagService.getInstance().decreasePostCount();
			//TODO:修改日期
			ArchiveService.getInstance().decreaseCount(post.getDate());
			TagService.getInstance().updateTags(oldPost.getTags(), new ArrayList<String>());
		}else if(!oldPost.isVisiable() && post.isVisiable()){
			TagService.getInstance().increasePostCount();
			ArchiveService.getInstance().increaseCount(post.getDate());
			TagService.getInstance().updateTags(new ArrayList<String>(), post.getTags());
		}else if(oldPost.isVisiable() && post.isVisiable()){
			TagService.getInstance().updateTags(oldPost.getTags(), post.getTags());
		}
		postDAO.updatePost(post);
		cache.clear();
	}
	
	/**
	 * 删除一个帖子
	 * @param id
	 */
	public void deletePostById(Long id){
		jalus.model.Post post = postDAO.getPostById(id);
		if(post.isVisiable()){
			TagService.getInstance().updateTags(post.getTags(), new ArrayList<String>());
			TagService.getInstance().decreasePostCount();
			ArchiveService.getInstance().decreaseCount(post.getDate());
		}
		postDAO.deletePostById(id);
		CommentService.getInstance().deleteAllcommentByPost(id);
		cache.clear();
	}
	/**
	 * 创建一个帖子
	 * @param post
	 * @return
	 */
	public Long addPost(jalus.model.Post post) {
		if(post.isVisiable()){
			TagService.getInstance().updateTags(new ArrayList<String>(), post.getTags());
			TagService.getInstance().increasePostCount();
			ArchiveService.getInstance().increaseCount(post.getDate());
		}
		Long id = postDAO.addPost(post);
		cache.clear();
		return id;
	}
	
	/**
	 *  最近的post列表;现在在sidebar中使用。 
	 */
	public List<jalus.pojo.Post> getRecentPost(int count) {
		return this.getPostList(null, 0, count);
	}
	
	/**
	 * 获取post的评论数
	 * @param post
	 * @return
	 */
	public int getCommentCountByPost(Long postId){
		return CommentService.getInstance().getCommentByPost(postId).size();
	}
	
	@SuppressWarnings("unchecked")
	public List<jalus.pojo.Post> getSpinPostList(){
		String key = "getSpinPostList";
		if(cache.containsKey(key)){
			return (List<jalus.pojo.Post>) cache.get(key);
		}
		List<jalus.pojo.Post> postList = PojoHandler.copyMToPList(postDAO.getSpinPostList());
		cache.put(key, postList);
		return postList;
	}
	
	public void clearCache(){
		this.cache.clear();
	}
	@SuppressWarnings("unchecked")
	public List<Post> getPostList(String tag, int offset, int length) {
		String key = "getPostList@" + tag + "_" + offset + "_" + length;
		if(cache.containsKey(key)){
			return (List<jalus.pojo.Post>) cache.get(key);
		}
		List<jalus.pojo.Post> postList;
		if(StringUtils.isEmpty(tag)){
			postList = PojoHandler.copyMToPList(postDAO.getRangePost(offset, offset + length));
		}else{
			postList = PojoHandler.copyMToPList(postDAO.getRangePostByTag(tag, offset, offset + length));
		}
		for(jalus.pojo.Post post : postList){
			post.setCommentCount(getCommentCountByPost(post.getId()));
		}
		cache.put(key, postList);
		return postList;
	}
}
